﻿#pragma once

//#include <cliext/vector>
#include <Windows.h>
#include <string>

#include "Q:\\includes\\ESP.h"
//#pragma comment(lib, "user32.lib")

//#define ENABLE__GET_EFI_INFO


using namespace System;
//using namespace cliext;

namespace ESPCS {
	public ref class ESP
	{
		
		/*
	/// <summary>
	/// 函数返回状态
	/// </summary>
	public: enum class FunctionStatus {
		/// <summary>
		/// 函数执行失败
		/// </summary>
		RET_ERROR = 0,

		/// <summary>
		/// 函数执行成功
		/// </summary>
		RET_OK = 1,
		};

	*/
#ifdef ENABLE__GET_EFI_INFO
	public: ref struct  EFI_PARTITION_INFOMATION
	{
		int DiskNumber;					//EFI分区所在硬盘编号，从0开始

		String^ PartionDrivePath; //分区路径，如"\\Device\\Harddisk0\\Partition1"，可通过该路径挂载和卸载EFI分区

		bool HasPartitionLetter;		//分区是否被挂载
		char PartitionLetter;			//分区卷标，若HasPartitionLetter为false则为0

	};
#endif

	/// <summary>
	/// 错误代码
	/// </summary>
	public: enum class ErrorCode {
		ESPCS_OK = 0,																					//无错误
		ESPCS_ERROR_GETDRVINFO_NODISK = ERROR_GETDRVINFO_NODISK,										//计算机中没有磁盘
		ESPCS_ERROR_GETDRVINFO_OPEN_DISK_FAIL = ERROR_GETDRVINFO_OPEN_DISK_FAIL,						//通过CreateFile打开磁盘失败
		ESPCS_ERROR_GETDRVINFO_GET_STRUCT_SIZE_FAIL = ERROR_GETDRVINFO_GET_STRUCT_SIZE_FAIL,			//获取结构体大小失败
		ESPCS_ERROR_GETDRVINFO_GET_STRUCT_FAIL = ERROR_GETDRVINFO_GET_STRUCT_FAIL,						//获取结构体失败

		ESPCS_ERROR_GETVOLUME_GET_VOLUME_MOUNT_PATH_FAIL = ERROR_GETVOLUME_GET_VOLUME_MOUNT_PATH_FAIL,	//获取卷挂载路径失败
		ESPCS_ERROR_GETESPINFO_NO_ESP_PARTITION = ERROR_GETESPINFO_NO_ESP_PARTITION,					//没有ESP分区
		ESPCS_ERROR_GETESPINFO_NO_MORE_AVAIBLE_LETTER = ERROR_GETESPINFO_NO_MORE_AVAIBLE_LETTER,		//没有多余盘符(获取可用盘符)
		ESPCS_ERROR_MOUNTESP_NO_MORE_AVAIBLE_LETTER = ERROR_MOUNTESP_NO_MORE_AVAIBLE_LETTER,			//没有多余盘符(挂载ESP)
		
		ESPCS_ERROR_UNKNOWN = 0xffffffffffffffff,														//未知错误
	};

	/// <summary>
	/// 硬盘号
	/// </summary>
	public:typedef short HardDiskNumber;

	/// <summary>
	/// 分区号
	/// </summary>
	public:typedef short PartitionNumber;


		/// <summary>
		/// 挂载所有EFI分区，已挂载的分区不会重复挂载
		/// </summary>
		/// <param name="MountedEspLetter">指向用于接收挂载的ESP分区盘符的指针</param>
		/// <returns>成功返回string,失败抛出异常，可使用GetLastError获取错误信息/returns>
	public: static String^ EspCs_MountEfiPartition();

		/// <summary>
		/// 挂载指定硬盘编号的EFI分区，已挂载的不会重新挂载
		/// </summary>
		/// <param name="DiskNumber">硬盘号，从0开始</param>
		/// <param name="MountedEspLetter">指向用于接收挂载的EFI分区盘符的指针</param>
		/// <returns>成功返回string,失败抛出异常，可使用GetLastError获取错误信息/returns>
	public: static String^ EspCs_MountEfiPartition(_In_ int DiskNumber);

		/// <summary>
		/// 卸载所有EFI分区，已卸载的不会重复卸载
		/// </summary>
		/// <param name="UnmountedEspLetter">指向用于接收卸载的EFI分区盘符的指针</param>
		/// <returns>成功返回string,失败抛出异常，可使用GetLastError获取错误信息/returns>
	public: static String^ EspCs_UnmountEfiPartition();

		/// <summary>
		/// 卸载指定EFI分区，已卸载的不会重复卸载
		/// </summary>
		/// <param name="Letter">盘符，例如"C","D"，字母必须大写</param>
		/// <returns>成功返回string,失败抛出异常，可使用GetLastError获取错误信息/returns>
	public: static String^ EspCs_UnmountEfiPartition(_In_ String^ Letter);

		/// <summary>
		/// 卸载指定硬盘编号的EFI分区，已卸载的不会重新卸载
		/// </summary>
		/// <param name="DiskNumber">硬盘号，从0开始</param>
		/// <param name="UnmountedEspLetter">指向用于接收卸载的EFI分区盘符的指针</param>
		/// <returns>成功返回string,失败抛出异常，可使用GetLastError获取错误信息/returns>
	public: static String^ EspCs_UnmountEfiPartition(_In_ int DiskNumber);

#ifdef ENABLE__GET_EFI_INFO
		/// <summary>
		/// 获取计算机上所有EFI分区信息(警告：本项目为“ESP”的CLI版本，最多获取128个EFI分区)
		/// </summary>
		/// <param name="Count">输出，数组长度</param>
		/// <param name="PartitionInfo">指向用于接收EFI分区信息的数组的指针</param>
		/// <returns>成功返回std::array，失败报错，可用GetLastError获取错误信息</returns>
	public:static std::array<ESPCS::ESP::EFI_PARTITION_INFOMATION^, 128> ESPCS::ESP::EspCs_GetEfiPartitionInfoTable(
		_Out_ int Count
	);
#endif

	/// <summary>
	/// 获取ESP_CS类库运行中的错误代码
	/// </summary>
	public: static ErrorCode EspCs_GetLastError();
		

	/// <summary>
	/// 通过盘符返回硬盘所在的硬盘号和分区号
	/// </summary>
	/// <param name="Letter">盘符，如“C”</param>
	/// <returns>成功后返回两个值(类型均为short)：第一个代表硬盘号，第二个代表分区号，失败则两个值均返回-1</returns>
	public: static std::pair<HardDiskNumber,PartitionNumber> EspCS_Partition_GetDriveInfoByLetter(char Letter);

	/// <summary>
	/// 通过盘符返回硬盘所在的硬盘号
	/// </summary>
	/// <param name="Letter">盘符，如“C”</param>
	/// <returns>成功后返回硬盘号，失败返回-1</returns>
	public: static HardDiskNumber EspCS_Partition_GetHardDiskNumberByLetter(unsigned char Letter);
	
	/// <summary>
	/// 通过盘符返回硬盘所在的分区号
	/// </summary>
	/// <param name="Letter">盘符，如“C”</param>
	/// <returns>成功后返回分区号，失败返回-1</returns>
	public: static PartitionNumber EspCS_Partition_GetPartitionNumberByLetter(unsigned char Letter);

	/// <summary>
	/// 获取计算机装载的硬盘数量
	/// </summary>
	/// <returns></returns>
	public:static int GetHarddiskNum();

	};
}
